﻿#include "WRWorkTcpCommService.h"
#include "WRWorkServiceType.h"
#include "WRWorkSwitchEvent.h"
#include "Servers/WRWorkTcpCommServer.h"
#include "Servers/WRWorkTcpCommServerObjRef.h"
#include "Runtime/WRWorkObjectActivator.h"
#include "../WRSoft-Utility/WRConfig.h"
#include "../WRSoft-Utility/Runtime/WRClass.h"

#include <QCoreApplication>

//表示工作TCP通讯服务激活器。
class WRWorkTcpCommServiceActivator : public WRWorkObjectActivator
{
public:
    //初始化工作TCP通讯服务激活器。
    WRWorkTcpCommServiceActivator(void)
    {
        QChar className[] = WRWorkTcpCommServiceStrArr;
        WRClass::enroll(WRWorkTcpCommServiceClass, QString(className, WRWorkTcpCommServiceStrLen), this);
    }
    //清理当前对象所占用的相关资源。
    ~WRWorkTcpCommServiceActivator(void)
    {
        //add code here
    }

    //创建工作服务实例。
    WRWorkObject* create(WRWorkDaemon* daemon, const QDomElement& config)
    {
        QChar portLiteral[] = {'p', 'o', 'r', 't'};
        QString portString = QString::fromRawData(portLiteral, 4);
        QChar autostartLiteral[] = {'a', 'u', 't', 'o', 's', 't', 'a', 'r', 't'};
        QString autostartString = QString::fromRawData(autostartLiteral, 9);

        QDomElement childNode = config.firstChildElement(portString);
        if (childNode.isNull())
        {
            return 0;
        }
        QString text = WRConfig::readValue(config, portString);
        if (text.isNull() || text.isEmpty())
        {
            return 0;
        }
        bool result = false;
        int port = text.toInt(&result);
        if (!result || port < 0 || port > 32768)
        {
            return 0;
        }

        bool autostart = true;
        text = WRConfig::readValue(config, autostartString);
        QChar falseLiteral[] = {'F', 'A', 'L', 'S', 'E'};
        QString falseString = QString::fromRawData(falseLiteral, 5);
        if (text.compare(falseString, Qt::CaseInsensitive) == 0)
        {
            autostart = false;
        }

        WRWorkInformation info;
        if (!info.create(config))
        {
            return 0;
        }

        return new WRWorkTcpCommService(info, daemon, (WR16u)port, autostart);
    }
};
//唯一实例。
static WRWorkTcpCommServiceActivator g_workTcpCommServiceActivator;

//初始化工作TCP通讯服务。
WRWorkTcpCommService::WRWorkTcpCommService(const WRWorkInformation& info, WRWorkDaemon* daemon, WR16u port, bool autostart)
    : WRWorkService(info, daemon)
{
    m_port = port;
    m_autostart = autostart;
    m_thread = 0;
    m_server = 0;
}
//释放当前对象所占用的相关资源。
WRWorkTcpCommService::~WRWorkTcpCommService(void)
{
    //add code here
}

//获取当前工作设备类型。
WRType* WRWorkTcpCommService::type(void) const
{
    return WRTypes::workLocalControlService();
}

//执行初始化处理。
void WRWorkTcpCommService::onInit(QList<WRWorkTcpCommServerObjRef*>& list, WRWorkObject* value, WRWorkTcpCommServerObjRef* parent)
{
    auto objRef = new WRWorkTcpCommServerObjRef((WR32s)list.size(), value, parent);
    list.append(objRef);

    auto& children = value->children();
    for(WRu i = 0, l = children.count(); i < l; ++i)
    {
        onInit(list, children[i], objRef);
    }
}
//当加载后执行相应的初始工作。
void WRWorkTcpCommService::onInit(void)
{
    m_timestamp.local();
    QList<WRWorkTcpCommServerObjRef*> list;
    auto& objects = daemon()->objects();
    for(WRu i = 0, l = objects.count(); i < l; ++i)
    {
        onInit(list, objects[i], nullptr);
    }
    m_objects=list;

    WRWorkObject::onInit();

    if (m_autostart)
    {
        start();
    }
}
//当删除前执行相应的清理工作。
void WRWorkTcpCommService::onFree(void)
{
    stop();

    for(WRu i = 0, l = m_objects.count(); i < l; ++i)
    {
        WRWorkTcpCommServerObjRef* entry = m_objects[i];
        delete entry;
    }

    WRWorkObject::onFree();
}

//启动服务，如果成功，则返回0。
WR32s WRWorkTcpCommService::start(void)
{
    QMutexLocker lck(&m_mutex);
    if (!m_thread)
    {
        m_thread = new QThread();
        m_thread->start();

        m_server = new WRWorkTcpCommServer();
        m_server->moveToThread(m_thread);

        QSemaphore mutex;
        int result = WRErrors::None;
        QCoreApplication::postEvent(m_server, new WRWorkSwitchEvent(&mutex, WRWorkSwitchEvent::Start, this, &result));
        mutex.acquire();

        if (result !=  WRErrors::None)
        {
            m_thread->exit();
            m_thread->wait();
            m_thread = 0;
            m_server = 0;
        }
        else
        {
            onStatusChanged(WRWorkStatus::Running);
        }
        return result;
    }
    return WRErrors::None;
}
//停止服务。
void WRWorkTcpCommService::stop(void)
{
    QMutexLocker lck(&m_mutex);
    if (m_thread)
    {
        m_server->deleteLater();
        m_thread->exit();
        m_thread->wait();
        m_thread = 0;

        onStatusChanged(WRWorkStatus::Stopped);
    }
}
